ExtJS একটি শক্তিশালী এবং ফিচার-প্যাকড জাভাস্ক্রিপ্ট ফ্রেমওয়ার্ক, তবে বড় এবং জটিল অ্যাপ্লিকেশন তৈরি করার সময় পারফরম্যান্স সমস্যা হতে পারে। ExtJS অ্যাপ্লিকেশনের পারফরম্যান্স অপটিমাইজেশন মূলত সঠিক কনফিগারেশন, কার্যকরী ডেটা ম্যানেজমেন্ট, এবং ফিচারগুলি ব্যবহারের মাধ্যমে অ্যাপ্লিকেশনের দ্রুততা এবং স্কেলেবিলিটি উন্নত করা হয়।
এখানে কিছু গুরুত্বপূর্ণ পারফরম্যান্স অপটিমাইজেশন টিপস এবং কৌশল প্রদান করা হচ্ছে, যা ExtJS অ্যাপ্লিকেশনগুলির পারফরম্যান্স উন্নত করতে সহায়ক।
১. Lazy Loading ব্যবহার করা
Lazy Loading হল একটি কৌশল যার মাধ্যমে অ্যাপ্লিকেশন শুধু তখনই ডেটা লোড করে যখন এটি প্রয়োজন হয়। একে ডিভাইডেড লোডিং বা ডাইনামিক লোডিংও বলা হয়। এর মাধ্যমে, অ্যাপ্লিকেশন শুরু হওয়ার সময় অপ্রয়োজনীয় ডেটা লোড করার ঝামেলা কমে যায়, ফলে পারফরম্যান্স উন্নত হয়।
Lazy Loading উদাহরণ:
Ext.create('Ext.data.Store', {
storeId: 'userStore',
fields: ['id', 'name', 'email'],
proxy: {
type: 'ajax',
url: 'users.json',
reader: {
type: 'json',
rootProperty: 'data'
}
},
autoLoad: false // অ্যাপ্লিকেশন শুরুতে ডেটা লোড করা হবে না
});
var store = Ext.getStore('userStore');
store.load(); // শুধুমাত্র যখন প্রয়োজন তখন ডেটা লোড করা হবে
এখানে:
autoLoad: falseকনফিগারেশন ব্যবহার করা হয়েছে যাতে অ্যাপ্লিকেশন শুরুতে ডেটা লোড না হয়।- ডেটা লোড করা হবে
store.load()মেথড কল করার মাধ্যমে, যখন সেটি প্রয়োজন হবে।
২. Data Binding অপটিমাইজেশন
ডেটা-বাইন্ডিংটি ExtJS অ্যাপ্লিকেশনের একটি গুরুত্বপূর্ণ অংশ, তবে এটি যদি সঠিকভাবে পরিচালিত না হয় তবে পারফরম্যান্সে নেতিবাচক প্রভাব ফেলতে পারে। Data Binding এর মাধ্যমে UI উপাদানগুলি ডেটার সাথে যুক্ত থাকে এবং ডেটা পরিবর্তিত হলে UI স্বয়ংক্রিয়ভাবে আপডেট হয়। তবে অতিরিক্ত ডেটা-বাইন্ডিং UI রেন্ডারিং ধীর করতে পারে।
Data Binding অপটিমাইজেশন উদাহরণ:
bindএবংupdateঅপটিমাইজেশন ব্যবহার করে শুধুমাত্র প্রয়োজনীয় অংশগুলির মধ্যে ডেটা-বাইন্ডিং পরিচালনা করা।
Ext.create('Ext.data.Store', {
storeId: 'userStore',
fields: ['id', 'name', 'email'],
data: [
{ id: 1, name: 'John Doe', email: 'john.doe@example.com' },
{ id: 2, name: 'Jane Smith', email: 'jane.smith@example.com' }
]
});
Ext.create('Ext.grid.Panel', {
title: 'User Grid',
store: Ext.data.StoreManager.lookup('userStore'),
columns: [
{ text: 'ID', dataIndex: 'id' },
{ text: 'Name', dataIndex: 'name' },
{ text: 'Email', dataIndex: 'email' }
],
renderTo: Ext.getBody()
});
এখানে:
Ext.data.StoreএবংExt.grid.Panelব্যবহার করে ডেটা-গ্রিড তৈরি করা হয়েছে, যেখানে ডেটা শুধুমাত্র প্রয়োজনীয় UI উপাদানে বাইন্ড করা হচ্ছে।
৩. Rendering অপটিমাইজেশন
অ্যাপ্লিকেশনে বড় সংখ্যক UI কম্পোনেন্ট বা গ্রিড থাকলে rendering পারফরম্যান্স সমস্যা তৈরি করতে পারে। বিশেষ করে, যখন প্রতিটি রেন্ডারিংয়ে বড় ডেটা সেট লোড হয়, তখন এটি অ্যাপ্লিকেশনের পারফরম্যান্সে বিরূপ প্রভাব ফেলতে পারে। Virtual Scrolling, Buffering, এবং Lazy Rendering ব্যবহার করা উচিত।
Rendering অপটিমাইজেশন উদাহরণ:
Ext.create('Ext.grid.Panel', {
title: 'User List',
store: {
fields: ['id', 'name', 'email'],
pageSize: 100, // প্রতি পেজে ১০০টি রেকর্ড
proxy: {
type: 'ajax',
url: 'users.json',
reader: {
type: 'json',
rootProperty: 'data'
}
}
},
columns: [
{ text: 'ID', dataIndex: 'id', flex: 1 },
{ text: 'Name', dataIndex: 'name', flex: 1 },
{ text: 'Email', dataIndex: 'email', flex: 1 }
],
infinite: true, // Virtual Scrolling
renderTo: Ext.getBody()
});
এখানে:
pageSize: 100সেট করে পেজিনেশন ব্যবহৃত হচ্ছে, যাতে একসাথে বড় ডেটা সেট লোড না হয়।infinite: trueএর মাধ্যমে ভার্চুয়াল স্ক্রলিং সক্ষম করা হয়েছে, যা বড় ডেটা সেটের রেন্ডারিং পারফরম্যান্স উন্নত করে।
৪. Memory Leak থেকে बचाव
এটি খুবই গুরুত্বপূর্ণ যে ExtJS অ্যাপ্লিকেশন মেমোরি লিক থেকে মুক্ত থাকে। যদি কোনো DOM উপাদান বা কম্পোনেন্টের রেফারেন্স ঠিকভাবে মুক্ত না হয়, তবে মেমোরি লিক হতে পারে যা অ্যাপ্লিকেশনের পারফরম্যান্সে নেতিবাচক প্রভাব ফেলবে। বিশেষ করে, Event Listeners, Components, Stores, ইত্যাদি মুক্ত করতে হবে।
Memory Leak Prevention:
var grid = Ext.create('Ext.grid.Panel', {
title: 'User Grid',
store: Ext.create('Ext.data.Store', {
fields: ['id', 'name', 'email'],
data: [{ id: 1, name: 'John Doe', email: 'john.doe@example.com' }]
}),
columns: [
{ text: 'ID', dataIndex: 'id' },
{ text: 'Name', dataIndex: 'name' },
{ text: 'Email', dataIndex: 'email' }
]
});
// Event Listener free when component is destroyed
grid.on('destroy', function() {
// Free up any resources
});
এখানে:
grid.on('destroy')এর মাধ্যমে কম্পোনেন্ট ধ্বংস হওয়ার পর যে কোনও রিসোর্স বা মেমোরি লিক মুক্ত করা হচ্ছে।
৫. Minification এবং Compression
কোনো অ্যাপ্লিকেশনের কোড ছোট এবং কম্প্রেসড হওয়া উচিত যাতে লোড টাইম কমে যায় এবং অ্যাপ্লিকেশন দ্রুত কাজ করে। ExtJS এ Sencha Cmd ব্যবহার করে আপনি কোড কম্প্রেস এবং মিনিফাই করতে পারেন।
Sencha Cmd দিয়ে Minification:
sencha app build production
এটি অ্যাপ্লিকেশনকে প্রোডাকশন বিল্ডে মিনিফাই এবং কম্প্রেস করবে, ফলে ফাইল সাইজ ছোট হবে এবং লোড টাইম কমে যাবে।
৬. Caching
Caching একটি কার্যকরী কৌশল যা অ্যাপ্লিকেশন পারফরম্যান্স উন্নত করতে সাহায্য করে, বিশেষ করে যখন ডেটার পুনরাবৃত্তি লোডের প্রয়োজন হয়। ExtJS তে LocalStorage বা SessionStorage ব্যবহার করে ডেটা ক্যাশ করা যেতে পারে।
Caching উদাহরণ:
var userStore = Ext.create('Ext.data.Store', {
fields: ['id', 'name', 'email'],
data: JSON.parse(localStorage.getItem('userData')) || [],
listeners: {
load: function() {
localStorage.setItem('userData', JSON.stringify(userStore.getData().items));
}
}
});
এখানে:
localStorage.setItem()এবংlocalStorage.getItem()ব্যবহার করে ডেটা ক্যাশ করা হচ্ছে।- প্রথমে ক্যাশ থেকে ডেটা নেওয়া হয় এবং নতুন ডেটা লোড হওয়ার পরে সেটি ক্যাশ করা হয়।
সারাংশ
- Lazy Loading: প্রয়োজনীয় ডেটা যখন দরকার তখনই লোড করা।
- Data Binding Optimization: অপ্রয়োজনীয় ডেটা-বাইন্ডিং কমিয়ে UI পারফরম্যান্স উন্নত করা।
- Rendering Optimization: ভার্চুয়াল স্ক্রলিং এবং Lazy Rendering ব্যবহার করা।
- Memory Leak Prevention: মেমোরি লিক রোধে DOM এবং রেফারেন্স ঠিকভাবে মুক্ত করা।
- Minification and Compression: কোড মিনিফাই ও কম্প্রেস করা।
- Caching: ডেটা ক্যাশিংয়ের মাধ্যমে লোড টাইম কমানো এবং পারফরম্যান্স উন্নত করা।
এই কৌশলগুলি ব্যবহার করে আপনি আপনার ExtJS অ্যাপ্লিকেশন পারফরম্যান্স আরও দ্রুত এবং স্কেলেবল করতে সক্ষম হবেন।
Memory Management এবং Performance Best Practices হল ওয়েব অ্যাপ্লিকেশন ডেভেলপমেন্টের অপরিহার্য অংশ, বিশেষত যখন আপনি বড়, জটিল, এবং ডেটা-ড্রিভেন অ্যাপ্লিকেশন তৈরি করেন। ExtJS, যেমন শক্তিশালী ইউজার ইন্টারফেস (UI) কম্পোনেন্ট সরবরাহ করে, তেমনই এটি মেমরি ব্যবস্থাপনা এবং পারফরম্যান্স অপটিমাইজেশনে সহায়ক টুলসও প্রদান করে। এই পোস্টে, আমরা আলোচনা করব কিভাবে আপনি ExtJS তে মেমরি ব্যবস্থাপনা করতে পারেন এবং পারফরম্যান্স অপটিমাইজেশন অর্জন করতে পারেন।
১. Memory Management in ExtJS
মেমরি ব্যবস্থাপনা ওয়েব অ্যাপ্লিকেশনে অতিরিক্ত মেমরি খরচ এবং লিক (memory leaks) রোধ করতে গুরুত্বপূর্ণ। ExtJS তে অ্যাপ্লিকেশনের মধ্যে ডায়নামিকভাবে UI উপাদান তৈরি এবং ধ্বংস করা হয়, তাই মেমরি লিকগুলি একটি বড় সমস্যা হয়ে দাঁড়াতে পারে।
Memory Leaks রোধ করতে কিছু সাধারণ টিপস:
Listeners এবং Event Handlers:
- যখন ইভেন্ট হ্যান্ডলারের মাধ্যমে DOM উপাদানগুলো তৈরি করা হয়, তখন সেগুলিকে আনলিঙ্ক (unlink) করা উচিত যাতে মেমরি ফাঁস না ঘটে। ExtJS তে
destroyমেথড ব্যবহার করে হ্যান্ডলার এবং লিসনারগুলি মুছে ফেলা যায়।
var button = Ext.create('Ext.Button', { text: 'Click Me', renderTo: Ext.getBody() }); // Event listener with cleanup button.on('click', function() { alert('Button clicked!'); }); // Cleanup after use button.destroy();- যখন ইভেন্ট হ্যান্ডলারের মাধ্যমে DOM উপাদানগুলো তৈরি করা হয়, তখন সেগুলিকে আনলিঙ্ক (unlink) করা উচিত যাতে মেমরি ফাঁস না ঘটে। ExtJS তে
Destroying Components:
- ExtJS তে যে কোনো কম্পোনেন্ট বা ভিউ যখন আর প্রয়োজন নেই তখন তার
destroy()মেথড ব্যবহার করে তা ধ্বংস করা উচিত। এটি DOM থেকে উপাদান মুছে দেয় এবং সংশ্লিষ্ট মেমরি ফ্রি করে।
var panel = Ext.create('Ext.panel.Panel', { title: 'Demo Panel', html: 'Content here' }); panel.destroy(); // Clean up when no longer needed- ExtJS তে যে কোনো কম্পোনেন্ট বা ভিউ যখন আর প্রয়োজন নেই তখন তার
- Avoiding Global Variables:
- গ্লোবাল ভেরিয়েবলগুলি অ্যাপ্লিকেশনের মেমরিতে এক্সেসযোগ্য থাকে এবং ডেটা রিটার্ন না করেই লিক সৃষ্টি করতে পারে। তাই গ্লোবাল ভেরিয়েবল ব্যবহার এড়িয়ে চলা উচিত।
Removing Unused Data Stores:
- Data Store গুলি কেবল তখনই মেমরিতে থাকতে পারে যখন সেগুলি প্রয়োজনীয়। ব্যবহার না হলে তাদের
destroy()করে দেওয়া উচিত। এটি অতিরিক্ত ডেটা লোডের থেকে মুক্তি দেয়।
var store = Ext.create('Ext.data.Store', { fields: ['name', 'email'], data: [{ name: 'John', email: 'john@example.com' }] }); store.destroy(); // Free memory when store is no longer needed- Data Store গুলি কেবল তখনই মেমরিতে থাকতে পারে যখন সেগুলি প্রয়োজনীয়। ব্যবহার না হলে তাদের
২. Performance Best Practices in ExtJS
একটি সঠিকভাবে অপটিমাইজড ExtJS অ্যাপ্লিকেশন দ্রুত লোড হয় এবং ব্যবহারকারী অভিজ্ঞতা উন্নত করে। ExtJS তে পারফরম্যান্স অপটিমাইজেশনের জন্য বেশ কিছু প্রযুক্তি রয়েছে, যা আপনার অ্যাপ্লিকেশনকে দ্রুত এবং দক্ষভাবে কাজ করতে সাহায্য করবে।
Performance Optimization Tips:
Lazy Loading (লেজি লোডিং):
- Lazy loading হল এমন একটি কৌশল যেখানে প্রয়োজন না হওয়া পর্যন্ত কোনও ডেটা বা কম্পোনেন্ট লোড করা হয় না। ExtJS তে
lazyLoadব্যবহার করে বড় ডেটাসেট বা কম্পোনেন্টকে পরবর্তীতে লোড করা যায়, যা অ্যাপ্লিকেশনের প্রথম লোড টাইম কমায়।
Ext.create('Ext.tree.Panel', { title: 'Lazy Loading Tree', store: Ext.create('Ext.data.TreeStore', { root: { expanded: true, children: [] }, proxy: { type: 'ajax', url: 'data/treedata.json', reader: { type: 'json', rootProperty: 'data' } } }), renderTo: Ext.getBody() });এখানে,
proxyব্যবহার করে JSON ফাইলটি লেজি লোডিং করা হয়েছে। এটা শুধুমাত্র প্রয়োজন হলে ডেটা লোড করবে।- Lazy loading হল এমন একটি কৌশল যেখানে প্রয়োজন না হওয়া পর্যন্ত কোনও ডেটা বা কম্পোনেন্ট লোড করা হয় না। ExtJS তে
Virtual Scrolling (ভার্চুয়াল স্ক্রোলিং):
- Virtual Scrolling ব্যবহার করে আপনি একটি বড় লিস্ট বা গ্রিড কম্পোনেন্টের ক্ষেত্রে কেবলমাত্র দৃশ্যমান আইটেমগুলো লোড করতে পারেন। এতে রেন্ডারিং প্রক্রিয়া দ্রুত হয় এবং মেমরি খরচ কমে।
Ext.create('Ext.grid.Panel', { title: 'Virtual Grid', store: { type: 'json', fields: ['name', 'email'], pageSize: 1000, // Large dataset pagination proxy: { type: 'ajax', url: 'large-data.json', reader: { type: 'json', rootProperty: 'data' } } }, columns: [ { text: 'Name', dataIndex: 'name' }, { text: 'Email', dataIndex: 'email' } ], viewConfig: { loadMask: true, scrollable: true // Enable virtual scrolling }, renderTo: Ext.getBody() });এখানে, ভার্চুয়াল স্ক্রোলিং ব্যবহার করে আমরা বড় ডেটাসেট পরিচালনা করছি এবং শুধুমাত্র প্রয়োজনীয় রেকর্ডগুলি লোড করছি।
Minification and Compression:
- Minification এবং Compression আপনার ExtJS অ্যাপ্লিকেশনকে অপটিমাইজ করতে সহায়ক। এটি কোডের আকার ছোট করে, যা পেজ লোডিং টাইম কমায়।
- Sencha Cmd টুল ব্যবহার করে আপনি আপনার অ্যাপ্লিকেশনটি মিনি, কনক্যাট এবং কম্প্রেস করতে পারেন।
sencha app build productionএই কমান্ডটি অ্যাপ্লিকেশনকে প্রোডাকশন পরিবেশের জন্য অপ্টিমাইজ করে এবং কোড ফাইলগুলো কম্প্রেস করে।
Avoiding Layout Thrashing:
- Layout Thrashing ঘটে যখন DOM উপাদানের লেআউট বারবার রেন্ডার হয়। এটি পারফরম্যান্সের জন্য খারাপ হতে পারে। নিশ্চিত করুন যে লেআউট পরিবর্তনগুলি একসাথে করা হচ্ছে এবং একাধিকবার রেন্ডারিং এড়ানো হচ্ছে।
// Instead of multiple layout changes var panel = Ext.create('Ext.panel.Panel', { title: 'My Panel', width: 100, height: 100 }); // Perform layout changes in one go panel.setSize(200, 200); // Avoid multiple resize triggersEfficient Event Handling:
- ইভেন্ট হ্যান্ডলারগুলি পারফরম্যান্সে প্রভাব ফেলতে পারে, তাই শুধুমাত্র প্রয়োজনীয় ইভেন্ট হ্যান্ডলার যোগ করা উচিত। ExtJS তে
event delegationব্যবহার করে একই ইভেন্ট হ্যান্ডলার বিভিন্ন উপাদানে অ্যাসাইন করা যেতে পারে।
// Delegate a click event for all child elements with 'my-button' class Ext.getBody().on('click', function(e, t) { if (t.className === 'my-button') { console.log('Button clicked'); } });- ইভেন্ট হ্যান্ডলারগুলি পারফরম্যান্সে প্রভাব ফেলতে পারে, তাই শুধুমাত্র প্রয়োজনীয় ইভেন্ট হ্যান্ডলার যোগ করা উচিত। ExtJS তে
৩. Testing and Profiling
Testing এবং Profiling এক্সটিজেএস অ্যাপ্লিকেশনের পারফরম্যান্স নির্ধারণ করতে সাহায্য করে। আপনি Sencha Inspector ব্যবহার করতে পারেন, যা অ্যাপ্লিকেশন এর পারফরম্যান্স পরীক্ষার জন্য একটি ডেভেলপার টুল।
Sencha Inspector:
- Sencha Inspector একটি ডেভেলপার টুল যা ExtJS অ্যাপ্লিকেশনগুলির পারফরম্যান্স এবং মেমরি ব্যবস্থাপনা বিশ্লেষণ করতে সহায়ক। এটি ব্যবহার করে আপনি অ্যাপ্লিকেশনের উপাদান এবং মডিউলগুলির পারফরম্যান্স দেখতে পারেন।
সারাংশ
- Memory Management:
- Listeners এবং Event Handlers সঠিকভাবে ক্লিনআপ করুন।
- Destroy মেথড ব্যবহার করে কম্পোনেন্ট ধ্বংস করুন।
- Global Variables এড়িয়ে চলুন।
- Performance Best Practices:
- Lazy Loading এবং Virtual Scrolling ব্যবহার করুন।
- Minification এবং Compression এর মাধ্যমে অ্যাপ্লিকেশন অপটিমাইজ করুন।
- Avoid Layout Thrashing এবং Efficient Event Handling করুন।
এই কৌশলগুলি অনুসরণ করে আপনি আপনার ExtJS অ্যাপ্লিকেশনকে আরও দ্রুত এবং মেমরি-এফিসিয়েন্ট করতে পারবেন।
Lazy Loading এবং Deferred Rendering দুটি গুরুত্বপূর্ণ কৌশল যা অ্যাপ্লিকেশনের পারফরম্যান্স এবং রেসপন্স টাইম উন্নত করার জন্য ব্যবহৃত হয়। ExtJS এ এই দুটি কৌশল ব্যবহৃত হয়, বিশেষত যখন আপনার অ্যাপ্লিকেশন বড় এবং জটিল হয় এবং আপনি ব্যবহারকারীদের জন্য দ্রুত এবং স্লো পেজ লোডিং অভিজ্ঞতা প্রদান করতে চান।
এখানে, আমরা Lazy Loading এবং Deferred Rendering এর কী, কীভাবে এগুলি কাজ করে এবং কীভাবে ExtJS এ এই কৌশলগুলি ব্যবহার করা যায় তা দেখব।
১. Lazy Loading (লেনি লোডিং)
Lazy Loading হল একটি কৌশল যেখানে ডেটা বা উপাদানগুলি শুধুমাত্র তখনই লোড করা হয় যখন সেগুলির প্রয়োজন হয়। এটি ব্যবহারকারীর জন্য দ্রুত লোডিং অভিজ্ঞতা প্রদান করতে সহায়ক, কারণ শুধুমাত্র প্রয়োজনীয় ডেটা লোড করা হয় এবং অ্যাপ্লিকেশনের বাকি অংশ অপেক্ষা করে না।
Lazy Loading এর মূল ধারণা:
- অ্যাপ্লিকেশনের স্টোর, গ্রিড বা কম্পোনেন্টের জন্য ডেটা বা উপাদানগুলি রিড/লোড করা হয় শুধুমাত্র যখন সেগুলির প্রয়োজন হয় (যেমন, পেজ স্ক্রোল করা বা ভিউতে উপাদান আসা)।
- এটি ব্রাউজারের রিসোর্স ব্যবহারে সাশ্রয় করে এবং প্রথম লোড টাইম দ্রুত করে।
ExtJS তে Lazy Loading উদাহরণ:
একটি ডেটা গ্রিডের জন্য Lazy Loading প্রয়োগ করা:
Ext.create('Ext.grid.Panel', {
title: 'Lazy Loaded Grid',
store: {
type: 'json',
proxy: {
type: 'ajax',
url: 'https://example.com/api/users',
reader: {
type: 'json',
rootProperty: 'data'
}
},
autoLoad: false, // স্বয়ংক্রিয়ভাবে লোড না করে শুধু প্রয়োজন হলে লোড হবে
pageSize: 50, // প্রতি পেজে ৫০টি রেকর্ড
},
columns: [
{ text: 'Name', dataIndex: 'name', flex: 1 },
{ text: 'Email', dataIndex: 'email', flex: 1 }
],
renderTo: Ext.getBody(),
loadMask: true
});
এখানে:
autoLoad: false: ডেটা প্রথমে লোড করা হবে না; শুধুমাত্র গ্রিডে ডেটা প্রয়োজন হলে লোড হবে।pageSize: 50: প্রতি পেজে ৫০টি রেকর্ড ডাইনামিকভাবে লোড করা হবে।proxy: Ajax রিকোয়েস্টের মাধ্যমে ডেটা লোড করা হচ্ছে।
Lazy Loading Benefits:
- পারফরম্যান্স উন্নতি: লোড টাইম কমিয়ে দ্রুত ফাস্ট লোড অভিজ্ঞতা প্রদান করা।
- রিসোর্স সাশ্রয়: প্রয়োজনীয় ডেটা কেবলমাত্র লোড করার ফলে ব্রাউজারের মেমরি ব্যবহারে সাশ্রয় হয়।
২. Deferred Rendering (ডেফার্ড রেন্ডারিং)
Deferred Rendering হল একটি কৌশল যেখানে UI উপাদানগুলি শুধুমাত্র তখন রেন্ডার করা হয় যখন সেগুলি দৃশ্যমান হয় বা ব্যবহারকারী ঐ উপাদানের সাথে ইন্টারঅ্যাক্ট করে। এটি UI রেন্ডারিং-এর সময় বিলম্বিত করার মাধ্যমে প্রথম লোডের সময় সাশ্রয় করতে সহায়ক।
Deferred Rendering এর মূল ধারণা:
- UI উপাদানগুলি শুধু তখনই রেন্ডার করা হয় যখন সেগুলি প্রয়োজন হয় (যেমন, ব্যবহারকারী স্ক্রোল করলে নতুন উপাদান দেখানো হয়)।
- এটি UI রেন্ডারিং-এর জন্য অতিরিক্ত রিসোর্স খরচ কমায় এবং অ্যাপ্লিকেশনের প্রথম লোডিং দ্রুত করে।
ExtJS তে Deferred Rendering উদাহরণ:
Ext.create('Ext.grid.Panel', {
title: 'Deferred Rendering Grid',
store: {
type: 'json',
proxy: {
type: 'ajax',
url: 'https://example.com/api/users',
reader: {
type: 'json',
rootProperty: 'data'
}
},
autoLoad: true,
pageSize: 50
},
columns: [
{ text: 'Name', dataIndex: 'name', flex: 1 },
{ text: 'Email', dataIndex: 'email', flex: 1 }
],
renderTo: Ext.getBody(),
viewConfig: {
// Deferred Rendering Enabling
preserveScrollOnRefresh: true, // স্ক্রোল অবস্থান সুরক্ষিত থাকবে
loadMask: true // লোড মাস্ক
}
});
এখানে:
viewConfig:preserveScrollOnRefreshব্যবহার করে স্ক্রোল অবস্থান রক্ষা করা হচ্ছে, অর্থাৎ নতুন ডেটা লোড হলে ইউজারের বর্তমান স্ক্রোল অবস্থান বজায় থাকবে।- Deferred Rendering-এর মাধ্যমে নতুন রেকর্ডগুলি রেন্ডার করা হয় শুধুমাত্র যখন সেগুলি ভিউয়ে আসবে।
Deferred Rendering Benefits:
- ইউজার ইন্টারফেস দ্রুত লোড হয়: শুধুমাত্র দৃশ্যমান উপাদান রেন্ডার হওয়ার কারণে প্রথম লোড দ্রুত হয়।
- রিসোর্স সাশ্রয়: UI উপাদানগুলোর অতিরিক্ত রেন্ডারিং কমিয়ে দেয়, যা ব্রাউজারের মেমরি ব্যবহারে সাশ্রয় করে।
৩. Lazy Loading এবং Deferred Rendering একসাথে ব্যবহার করা
যখন আপনি Lazy Loading এবং Deferred Rendering একসাথে ব্যবহার করেন, তখন এটি আরো বেশি পারফরম্যান্সের উন্নতি সাধন করতে সাহায্য করে, কারণ ডেটা এবং UI উপাদানগুলি শুধুমাত্র প্রয়োজনের ভিত্তিতে লোড এবং রেন্ডার করা হয়।
উদাহরণ: Lazy Loading এবং Deferred Rendering একসাথে
Ext.create('Ext.grid.Panel', {
title: 'Lazy Load & Deferred Rendering Grid',
store: {
type: 'json',
proxy: {
type: 'ajax',
url: 'https://example.com/api/users',
reader: {
type: 'json',
rootProperty: 'data'
}
},
autoLoad: false, // Lazy load
pageSize: 50
},
columns: [
{ text: 'Name', dataIndex: 'name', flex: 1 },
{ text: 'Email', dataIndex: 'email', flex: 1 }
],
renderTo: Ext.getBody(),
viewConfig: {
preserveScrollOnRefresh: true, // Deferred Rendering
loadMask: true
},
listeners: {
render: function() {
this.store.load(); // Store data will be loaded lazily
}
}
});
এখানে:
autoLoad: false: ডেটা লোড শুরু হবে শুধুমাত্র যখন গ্রিড দৃশ্যমান হবে।viewConfig:preserveScrollOnRefreshব্যবহারের মাধ্যমে স্ক্রোল অবস্থান সুরক্ষিত থাকে এবংloadMaskএর মাধ্যমে লোডিং ইন্ডিকেটর দেখানো হয়।
সারাংশ
- Lazy Loading: যখন প্রয়োজন হবে তখন ডেটা বা উপাদানগুলি লোড করা হয়, যা প্রথম লোডের সময় দ্রুত করার জন্য ব্যবহার করা হয়।
- Deferred Rendering: UI উপাদানগুলি শুধু তখনই রেন্ডার করা হয় যখন সেগুলি দৃশ্যমান হয়, যা পারফরম্যান্স উন্নত করতে সাহায্য করে।
- Lazy Loading এবং Deferred Rendering একসাথে: এই দুটি কৌশল একসাথে ব্যবহার করে আপনি ডেটা এবং UI উপাদানগুলিকে প্রয়োজনীয় সময়েই লোড ও রেন্ডার করতে পারবেন, যা অ্যাপ্লিকেশনের পারফরম্যান্স এবং ইউজার এক্সপিরিয়েন্সকে উন্নত করে।
এভাবে, Lazy Loading এবং Deferred Rendering ব্যবহার করে আপনি বড় এবং জটিল অ্যাপ্লিকেশনগুলিকে দ্রুত এবং দক্ষভাবে পরিচালনা করতে পারেন, যা ব্যবহারকারীদের জন্য একটি স্মুথ এক্সপিরিয়েন্স প্রদান করে।
Store এবং Component Caching হল ExtJS-এর দুটি গুরুত্বপূর্ণ ফিচার, যা অ্যাপ্লিকেশন পারফরম্যান্স এবং ডেটা ম্যানেজমেন্টে সাহায্য করে। Store ডেটা পরিচালনা করে এবং Component Caching ইউজার ইন্টারফেস উপাদানগুলিকে ক্যাশে করে যাতে পুনরায় ব্যবহারযোগ্য হয়। এই দুটি ফিচারকে সঠিকভাবে ব্যবহার করলে অ্যাপ্লিকেশন আরও দ্রুত এবং স্কেলেবল হয়।
১. Store in ExtJS
Store হল একটি ডেটা ম্যানেজমেন্ট কম্পোনেন্ট যা ExtJS অ্যাপ্লিকেশনগুলিতে ডেটার স্টোরেজ এবং ম্যানিপুলেশন পরিচালনা করে। একটি Store সাধারণত ডেটা লোড করা, ফিল্টার করা, সোর্ট করা এবং রেকর্ডের সাথে কাজ করার জন্য ব্যবহৃত হয়।
Store উদাহরণ:
Ext.create('Ext.data.Store', {
storeId: 'userStore',
fields: ['id', 'name', 'email'],
data: [
{ id: 1, name: 'John Doe', email: 'john@example.com' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }
],
proxy: {
type: 'memory', // স্মৃতি ভিত্তিক স্টোর
reader: {
type: 'json',
rootProperty: 'data'
}
}
});
এখানে:
fields: স্টোরের মধ্যে ডেটার ফিল্ডগুলির নাম নির্ধারণ করা হয়েছে।data: স্টোরে ডেটা লোড করা হয়েছে। এটি সরাসরি ডাটা লোড করার জন্য ব্যবহৃত হয়।proxy: স্টোরের জন্য ডেটা রিডার এবং ডেটা টাইপ (যেমন: memory বা ajax) নির্ধারণ করা হয়েছে।
Store এর বিভিন্ন কার্যক্রম:
- Data Filtering:
var store = Ext.getStore('userStore');
store.filter('name', 'John'); // 'John' নামের সাথে মিলে এমন ডেটা ফিল্টার করা হবে
- Sorting:
store.sort('name', 'ASC'); // 'name' ফিল্ডে Ascending অর্ডারে সোর্ট করা হবে
- Loading Data (Ajax Request):
var store = Ext.create('Ext.data.Store', {
proxy: {
type: 'ajax',
url: 'data.json', // সার্ভার থেকে JSON ডেটা লোড হবে
reader: {
type: 'json',
rootProperty: 'data'
}
},
autoLoad: true
});
এখানে, proxy কনফিগারেশন দিয়ে সার্ভার থেকে ডেটা লোড করা হচ্ছে।
২. Component Caching in ExtJS
Component Caching হল ExtJS-এর একটি পদ্ধতি যা UI কম্পোনেন্টগুলির পুনঃরেন্ডারিং এবং অপ্রয়োজনীয় লোডিং কমিয়ে দেয়। যখন UI কম্পোনেন্টগুলি পুনরায় ব্যবহৃত হয়, তখন সেগুলিকে আবার লোড বা রেন্ডার করার পরিবর্তে ক্যাশে করা হয়।
Component Caching ব্যবহারের সুবিধা:
- পারফরম্যান্স বৃদ্ধি: UI কম্পোনেন্টগুলি পুনরায় লোড করার পরিবর্তে ক্যাশে করা হলে অ্যাপ্লিকেশন দ্রুত হয়।
- নমনীয়তা: ডাইনামিকভাবে UI কম্পোনেন্টগুলি যোগ বা মুছে ফেলা হলেও আগের কম্পোনেন্টগুলো ক্যাশে থেকে রেন্ডার হতে থাকে।
- রিসোর্স সাশ্রয়: অতিরিক্ত রেন্ডারিং বা লোডিং থেকে রিসোর্স সাশ্রয় করা যায়।
Component Caching উদাহরণ:
Ext.create('Ext.panel.Panel', {
title: 'My Panel',
width: 300,
height: 200,
renderTo: Ext.getBody(),
html: 'Hello, this is a cached panel!',
cacheable: true // ক্যাশে করার জন্য
});
এখানে, cacheable: true প্রপার্টি কম্পোনেন্টকে ক্যাশে করার জন্য সেট করা হয়েছে, যাতে পুনরায় ব্যবহার করলে এটি পুনরায় রেন্ডার না হয়ে ক্যাশ থেকে আসবে।
Ext.ComponentCache ব্যবহার:
ExtJS তে Ext.ComponentCache নামক একটি ক্লাস রয়েছে, যা ক্যাশে কম্পোনেন্ট পরিচালনা করে। এটি কম্পোনেন্টগুলিকে ক্যাশে করতে এবং পুনরায় ব্যবহারযোগ্য করতে সহায়তা করে।
Ext.create('Ext.ComponentCache', {
id: 'myCachedPanel',
component: {
xtype: 'panel',
title: 'My Cached Panel',
html: 'This panel is cached for reuse.'
}
});
// Reuse the cached component
var cachedPanel = Ext.ComponentCache.get('myCachedPanel');
cachedPanel.show();
এখানে:
Ext.ComponentCacheব্যবহার করে কম্পোনেন্টটি ক্যাশে করা হয়েছে এবং পুনরায় সেটি ব্যবহার করা হয়েছে।
৩. Cache Management
ক্যাশ ম্যানেজমেন্টের মাধ্যমে আপনি ক্যাশের মধ্যে সঠিক ডেটা সংরক্ষণ এবং পুরানো বা অপ্রয়োজনীয় ডেটা পরিষ্কার করতে পারবেন।
Cache Expiration:
কিছু ক্যাশ ডেটার জন্য সময়সীমা (TTL) নির্ধারণ করা যায়, যাতে ডেটার মেয়াদ শেষ হলে তা স্বয়ংক্রিয়ভাবে মুছে ফেলা হয়।
var store = Ext.create('Ext.data.Store', {
storeId: 'userStore',
fields: ['id', 'name', 'email'],
data: [
{ id: 1, name: 'John Doe', email: 'john@example.com' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }
],
proxy: {
type: 'memory',
reader: {
type: 'json',
rootProperty: 'data'
},
ttl: 300000 // ক্যাশের মেয়াদ 5 মিনিট (300000 মিলিসেকেন্ড)
}
});
এখানে:
ttl(Time-to-live) প্রপার্টি দিয়ে স্টোরের ক্যাশের মেয়াদ নির্ধারণ করা হয়েছে, যাতে 5 মিনিট পর ক্যাশ মুছে যায়।
৪. Store এবং Component Caching এর সমন্বয়
একটি কার্যকরী অ্যাপ্লিকেশন তৈরির জন্য আপনি Store এবং Component Caching একত্রিতভাবে ব্যবহার করতে পারেন, যাতে ডেটা এবং UI দুটি সঠিকভাবে ক্যাশে করা যায় এবং অ্যাপ্লিকেশন পারফরম্যান্স বৃদ্ধি পায়।
Example: Store and Component Caching
// Store with memory proxy
var store = Ext.create('Ext.data.Store', {
storeId: 'userStore',
fields: ['id', 'name', 'email'],
proxy: {
type: 'memory',
reader: {
type: 'json',
rootProperty: 'data'
}
},
autoLoad: true
});
// Component with caching
Ext.create('Ext.panel.Panel', {
title: 'User Information',
renderTo: Ext.getBody(),
width: 400,
height: 200,
html: 'Loading user data...',
cacheable: true, // Component caching
listeners: {
afterrender: function() {
var panel = this;
store.load({
callback: function(records, operation, success) {
if (success) {
panel.update('<ul>' + records.map(function(record) {
return '<li>' + record.get('name') + ' - ' + record.get('email') + '</li>';
}).join('') + '</ul>');
}
}
});
}
}
});
এখানে:
store.load()ব্যবহার করে ডেটা লোড করা হচ্ছে এবং তারপর কম্পোনেন্টেরhtmlআপডেট করা হচ্ছে।cacheable: trueব্যবহার করে কম্পোনেন্টটি ক্যাশে করা হচ্ছে, যাতে পরবর্তী সময়ে দ্রুত রেন্ডার করা যায়।
সারাংশ
- Store: ExtJS এর Store কম্পোনেন্টটি ডেটা ম্যানেজমেন্টের জন্য ব্যবহৃত হয় এবং এটি ডেটা ফিল্টার, সোর্ট, লোড, এবং ম্যানিপুলেট করার জন্য ব্যবহৃত হয়।
- Component Caching: UI কম্পোনেন্টগুলি ক্যাশে করা হলে, এগুলিকে পুনরায় লোড বা রেন্ডার না করে দ্রুত পুনরায় ব্যবহৃত করা যায়, যা অ্যাপ্লিকেশন পারফরম্যান্স উন্নত করে।
- Cache Management: ক্যাশ ম্যানেজমেন্টের মাধ্যমে ডেটা সঠিকভাবে সংরক্ষণ এবং অপ্রয়োজনীয় ডেটা মুছে ফেলা যায়।
- Store and Component Caching Integration: ডেটা এবং UI কম্পোনেন্টের ক্যাশিং একত্রিত করে অ্যাপ্লিকেশনের স্কেলেবিলিটি এবং পারফরম্যান্স বৃদ্ধি করা যায়।
এটি একটি অত্যন্ত কার্যকরী কৌশল যা ডেটার ম্যানিপুলেশন এবং ইউজার ইন্টারফেস অপটিমাইজেশনে সহায়ক।
Large Data Handling এবং Virtual Scrolling হল এমন দুটি কৌশল যা ওয়েব অ্যাপ্লিকেশনগুলির কার্যক্ষমতা এবং ব্যবহারকারীর অভিজ্ঞতা উন্নত করতে সহায়ক, বিশেষত যখন অ্যাপ্লিকেশন বিশাল পরিমাণ ডেটা প্রদর্শন করে। ExtJS এর মাধ্যমে আপনি এই দুইটি ফিচার দক্ষভাবে ব্যবহার করতে পারবেন, যা আপনাকে বড় ডেটাসেটের সাথে কাজ করতে সহায়তা করবে এবং ইউজার ইন্টারফেসের প্রতিক্রিয়া দ্রুত রাখবে।
এখানে আমরা Large Data Handling এবং Virtual Scrolling এর ধারণা এবং কিভাবে এটি ExtJS তে ইমপ্লিমেন্ট করা যায়, তা আলোচনা করব।
১. Large Data Handling
যখন আপনার অ্যাপ্লিকেশন বড় ডেটাসেট (যেমন হাজার বা লাখ লাখ রেকর্ড) নিয়ে কাজ করে, তখন পুরো ডেটা একসাথে লোড করা ইউজারের জন্য দেরি সৃষ্টি করতে পারে এবং ব্রাউজারের পারফরম্যান্সে প্রভাব ফেলতে পারে। Large Data Handling এর মাধ্যমে আমরা কেবল প্রয়োজনীয় ডেটা লোড করি এবং কাস্টমাইজড ডেটা ফিল্টার, পেজিনেশন, এবং লেজি লোডিং ব্যবহারের মাধ্যমে ডেটাকে দক্ষভাবে পরিচালনা করি।
Large Data Handling এর কিছু কৌশল:
- Lazy Loading (লেজি লোডিং): অ্যাপ্লিকেশন শুধুমাত্র সেই ডেটা লোড করে যা ব্যবহারকারী দেখতে চায়।
- Pagination (পেজিনেশন): ডেটাকে পেজে ভাগ করে দেখানো, যেখানে একসাথে একটি নির্দিষ্ট পরিমাণ ডেটা দেখানো হয়।
- Dynamic Data Filtering: ব্যবহারকারীর ইন্টারঅ্যাকশনের ভিত্তিতে ডেটা ফিল্টার করা।
২. Virtual Scrolling (ভার্চুয়াল স্ক্রোলিং)
Virtual Scrolling বা Infinite Scrolling হল একটি কৌশল যেখানে শুধুমাত্র দৃশ্যমান ডেটা বা দৃশ্যমান অংশের ডেটা লোড করা হয়, অর্থাৎ যখন আপনি স্ক্রোল করেন, তখন নতুন ডেটা লোড হয়। এটি ব্যবহারকারীদের বড় ডেটাসেট দেখানোর একটি সাশ্রয়ী পদ্ধতি, যেহেতু আপনি সমস্ত ডেটা একসাথে লোড না করে প্রয়োজন অনুযায়ী ডেটা লোড করেন।
ExtJS তে ভার্চুয়াল স্ক্রোলিং ব্যবহারের মাধ্যমে আপনি কম্পোনেন্ট বা গ্রিডে অল্প ডেটা দেখাতে পারেন, যখন স্ক্রল করা হবে তখন অবশিষ্ট ডেটা লোড হবে।
Virtual Scrolling এর সুবিধা:
- পারফরম্যান্স: স্ক্রিনের বাইরে থাকা ডেটা লোড না করার কারণে অ্যাপ্লিকেশন দ্রুত কাজ করে।
- ইউজার এক্সপেরিয়েন্স: ব্যবহারকারী ইন্টারঅ্যাকশন মসৃণ হয় কারণ ডেটা লোডিং প্রতিটি স্ক্রোলের সাথে ঘটে।
৩. Virtual Scrolling Implementation in ExtJS
Virtual Scrolling বাস্তবায়ন করতে, ExtJS এর Ext.grid.Panel বা Ext.data.Store এর সাথে infinite scrolling বা virtual store ব্যবহার করা হয়।
Virtual Scrolling এর উদাহরণ:
Ext.create('Ext.data.Store', {
storeId: 'userStore',
fields: ['id', 'name', 'email'],
pageSize: 100, // প্রতিটি পেজে 100টি আইটেম দেখানো হবে
proxy: {
type: 'ajax',
url: 'https://example.com/api/users', // ডেটা লোড করার URL
reader: {
type: 'json',
rootProperty: 'data', // JSON ডেটার মূল অংশ
totalProperty: 'total' // মোট রেকর্ড সংখ্যা
}
},
autoLoad: true
});
Ext.create('Ext.grid.Panel', {
title: 'User List with Virtual Scrolling',
store: Ext.data.StoreManager.lookup('userStore'),
columns: [
{ text: 'ID', dataIndex: 'id', flex: 1 },
{ text: 'Name', dataIndex: 'name', flex: 2 },
{ text: 'Email', dataIndex: 'email', flex: 3 }
],
height: 400,
width: 600,
renderTo: Ext.getBody(),
loadMask: true, // ডেটা লোডের সময় লোড মাস্ক দেখাবে
viewConfig: {
trackOver: false, // স্ক্রলিংয়ের সময় সেল হাইলাইট না করার জন্য
stripeRows: true, // পঙক্তিগুলিতে স্ট্রাইপ যোগ করা হবে
listeners: {
// ভার্চুয়াল স্ক্রোলিং এর জন্য ইভেন্ট
bufferresize: function() {
var grid = this.up('grid');
var store = grid.getStore();
var view = grid.getView();
var total = store.getCount();
var visibleRows = view.getVisibleRange().length;
if (total <= visibleRows) return;
var currentIndex = store.getCount();
var nextPage = Math.floor(currentIndex / 100) + 1;
store.loadPage(nextPage); // পরবর্তী পেজ লোড করুন
}
}
}
});
এখানে:
pageSize: 100: প্রতি পেজে 100টি রেকর্ড লোড করা হচ্ছে।bufferresize: যখন গ্রিডের ভিউ আংশিকভাবে পরিবর্তিত হয় (যেমন স্ক্রল করা), তখন এটি নতুন ডেটা লোড করবে।store.loadPage(nextPage): এটি পরবর্তী পেজটি লোড করার জন্য ব্যবহৃত হয়।
Virtual Scrolling এবং Lazy Loading:
- Lazy Loading ব্যবহার করা হয়েছে যেখানে স্ক্রলিংয়ের মাধ্যমে পরবর্তী ডেটা লোড হয়, যা অ্যাপ্লিকেশনের পারফরম্যান্স বাড়ায়।
totalPropertyব্যবহার করে সার্ভার থেকে মোট রেকর্ড সংখ্যা পাঠানো হচ্ছে, যাতে আমরা ডেটা লোড করার জন্য কাস্টম লজিক প্রয়োগ করতে পারি।
৪. Large Data Handling with Paging
বড় ডেটাসেটের জন্য paging একটি গুরুত্বপূর্ণ কৌশল। Paging ব্যবহারকারীদের pageSize অনুযায়ী ডেটার পৃষ্ঠাগুলি ভাগ করে দেখায়। ExtJS তে পেজিং ব্যবহারের জন্য Ext.PagingToolbar ব্যবহার করা হয়।
Paging Example:
Ext.create('Ext.grid.Panel', {
title: 'Paginated Grid',
store: Ext.create('Ext.data.Store', {
pageSize: 50, // প্রতি পেজে 50টি রেকর্ড দেখানো হবে
proxy: {
type: 'ajax',
url: 'https://example.com/api/users', // সার্ভার থেকে ডেটা লোড
reader: {
type: 'json',
rootProperty: 'data',
totalProperty: 'total'
}
},
autoLoad: true
}),
columns: [
{ text: 'ID', dataIndex: 'id', flex: 1 },
{ text: 'Name', dataIndex: 'name', flex: 2 },
{ text: 'Email', dataIndex: 'email', flex: 3 }
],
height: 400,
width: 600,
renderTo: Ext.getBody(),
bbar: {
xtype: 'pagingtoolbar',
displayInfo: true, // পেজ তথ্য প্রদর্শন
store: Ext.data.StoreManager.lookup('userStore') // পেজিং টুলবারে স্টোর সেট করা
}
});
এখানে:
pageSize: 50: প্রতি পেজে 50টি আইটেম দেখানো হচ্ছে।bbar: পেজিং টুলবার যোগ করা হয়েছে যা ডেটার পৃষ্ঠাগুলোর মধ্যে নেভিগেট করতে সহায়ক।
৫. Performance Considerations for Large Data
যখন আপনি বড় ডেটাসেট পরিচালনা করেন, তখন কিছু পারফরম্যান্স বিষয় খেয়াল রাখতে হবে:
- Server-side Pagination: সার্ভারের মাধ্যমে ডেটা পেজিনেশন পরিচালনা করা। এতে, সার্ভার থেকে শুধুমাত্র প্রয়োজনীয় ডেটা লোড হবে এবং ক্লায়েন্টে লোড করার প্রয়োজন হবে না।
- Caching: লোড করা ডেটা ক্যাশে রাখা যাতে পুনরায় একই ডেটা না লোড করতে হয়।
- Data Filtering: ফিল্টারিং সার্ভার সাইডে করা, যাতে ক্লায়েন্টে সব ডেটা লোড না হয়।
সারাংশ
- Virtual Scrolling: ভার্চুয়াল স্ক্রোলিং মাধ্যমে শুধুমাত্র দৃশ্যমান ডেটা লোড করা হয়, যা বড় ডেটাসেটের পারফরম্যান্স বাড়ায়।
- Large Data Handling: Lazy loading, paging, এবং filtering ব্যবহার করে বড় ডেটাসেটটি কার্যকরভাবে ম্যানেজ করা হয়।
- ExtJS Performance Optimization: ExtJS তে বড় ডেটাসেট পরিচালনার জন্য সার্ভার সাইড পেজিনেশন, ক্যাশিং, এবং ডেটা ফিল্টারিং ব্যবহৃত হয়।
এভাবে, আপনি ExtJS ব্যবহার করে দক্ষভাবে বড় ডেটাসেট পরিচালনা এবং ভার্চুয়াল স্ক্রোলিং প্রয়োগ করতে পারবেন, যা অ্যাপ্লিকেশনকে দ্রুত এবং স্নিগ্ধ রাখতে সাহায্য করবে।
Read more